﻿// Shader-Based-Image-Processing (SBIP)
// http://code.google.com/p/sbip/
//
// Copyright © Frank Nagl, 2009-2010
// admin@franknagl.de
//
namespace SBIP.Filter
{
    using Microsoft.Xna.Framework.Graphics;
    using System;

    /// <summary>
    /// Threshold filter for every rgb channel with or without binarization.
    /// </summary>
    /// 
    /// <remarks>
    /// <para>
    /// The filter does rgb-threshold filtering using specified threshold values for every channel. 
    /// Every channel with intensity equal or lower than its threshold value is converted to black 
    /// channel (value 0). All other channels are converted to white channels (value 255), 
    /// when binarization is set. Otherwise the channels don't change.
    /// </para>
    /// 
    /// <para>Sample usage:</para>
    /// <code>
    ///  // 1. Offline rendering
    ///  // create Processor, used as rendering framework
    ///  Processor processor = new Processor();
    ///  // starts Processor
    ///  processor.Begin( image );
    ///  // create ThresholdRGB filter
    ///  ThresholdRGB filter = new ThresholdRGB( );
    ///  processor.Filter = filter;
    ///  // optional: configure filter
    ///  filter.R = 220;
    ///  filter.G = 80;
    ///  filter.B = 60;
    ///  filter.Binarization = true;
    ///  // apply the filter  
    ///  Bitmap resultImage = processor.RenderToBitmap( );
    ///  Texture2D resultTexture = processor.RenderToTexture( );
    ///  processor.End( );
    ///  
    ///  // 2. Online rendering
    ///  // create any windows control for rendering in
    ///  Form myForm = new Form( );
    ///  // create Processor, used as rendering framework
    ///  Processor processor2 = new Processor( );
    ///  // starts Processor
    ///  processor2.Begin( image, myForm );
    ///  // create ThresholdRGB filter
    ///  ThresholdRGB filter2 = new ThresholdRGB( );
    ///  processor2.Filter = filter2; 
    ///  // optional: configure filter
    ///  filter2.R = 220;
    ///  filter2.G = 80;
    ///  filter2.B = 60;
    ///  filter2.Binarization = false;
    ///  // apply the filter
    ///  myForm.Show( );
    ///  while ( myForm.Created )
    ///  {
    ///      processor2.Render( );
    ///      Application.DoEvents( );
    ///  }
    ///  processor2.End( );
    /// </code>
    /// 
    /// <para><b>Initial image:</b></para>
    /// <img src="img/shaderbased/sample1.jpg" width="480" height="361" />
    /// <para><b>Result image (with binarization):</b></para>
    /// <img src="img/shaderbased/ThresholdRGBBinarization.jpg" width="480" height="361" />
    /// <para><b>Result image (without binarization):</b></para>
    /// <img src="img/shaderbased/ThresholdRGB.jpg" width="480" height="361" />
    /// </remarks>
    public sealed class ThresholdRGB : BaseFilter
    {
        bool binarization;
        private byte r;
        private byte g;
        private byte b;

        /// <summary>If true filter does channel binairzation.</summary>
        /// <remarks><para>Default value is set to false.</para></remarks>
        public bool Binarization
        {
            get { return binarization; }
            set
            {
                if (Effect == null)
                    throw new ArgumentException("Binarization" + InitMsg);

                binarization = value;
                Effect.Parameters["Binarization"].SetValue(binarization);
            }
        }

        /// <summary>Threshold value for channel red.</summary>
        /// <remarks><para>Default value is set to 100.</para></remarks>
        public byte R
        {
            get { return r; }
            set
            {
                if (Effect == null)
                    throw new ArgumentException("Threshold for channel red" + InitMsg);

                r = value;
                Effect.Parameters["R"].SetValue(r);
            }
        }

        /// <summary>Threshold value for channel green.</summary>
        /// <remarks><para>Default value is set to 100.</para></remarks>
        public byte G
        {
            get { return g; }
            set
            {
                if (Effect == null)
                    throw new ArgumentException("Threshold for channel green" + InitMsg);

                g = value;
                Effect.Parameters["G"].SetValue(g);
            }
        }

        /// <summary>Threshold value for channel blue.</summary>
        /// <remarks><para>Default value is set to 100.</para></remarks>
        public byte B
        {
            get { return b; }
            set
            {
                if (Effect == null)
                    throw new ArgumentException("Threshold for channel blue" + InitMsg);

                b = value;
                Effect.Parameters["B"].SetValue(b);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="Threshold"/> class.
        /// </summary>
        public ThresholdRGB()
            : base("ThresholdRGB") { }

        /// <summary>
        /// Initializes threshold values.
        /// </summary>
        protected override void PostInit()
        {
            R = 100;
            G = 100;
            B = 100;
        }
    }
}
